<!--
 * @Descripttion: 左侧树
 * @version: V1.0.0
 * @Author: Shuangshuang Song
 * @LastEditors: Shuangshuang Song
 * @Date: 2020-05-23 15:23:04
 * @LastEditTime: 2021-01-04 14:18:05
-->
<template>
  <div class="left-tree">
    <div class="top-input">
      <el-autocomplete
        v-model="filterText"
        :fetch-suggestions="querySearch"
        @select="handleSelect"
        :trigger-on-focus="false"
        :placeholder="$t('PlaceHolder')"
        popper-class="person-select-autocomplete"
        size="small"
        clearable
        class="person-select-input"
      >
        <i
          slot="prefix"
          class="el-icon-search el-input__icon"
        />
        <template slot-scope="{ item }">
          <div class="name">
            {{ item.text }}
          </div>
          <span class="addr">{{ item.bean.DEPTNAME || item.bean.PARENTTEXT }}</span>
        </template>
      </el-autocomplete>
    </div>
    <div
      :class="'btree-' + type"
      class="bottom-tree"
    >
      <el-tree
        ref="tree"
        :data="getTreeData"
        :props="props"
        :load="loadNode"
        @check="handleCheck"
        @check-change="handleCheckChange"
        @node-click="handleNodeClick"
        @node-expand="handleNodeExpand"
        :default-expanded-keys="expandIds"
        :filter-node-method="filterNode"
        :show-checkbox="options.selectType != 'single'"
        :default-expand-all="type == 'common'"
        :lazy="async"
        :empty-text="nodataText"
        node-key="id_"
        highlight-current
      >
        <span
          slot-scope="{ node, data }"
          @dblclick="handleDbclick(node, data)"
          class="custom-tree-node"
        >
          <span class="node-icon">
            <i
              v-if="data.leaf"
              :style="{'color': data.bean.GENDER == 'WOMAN' ? '#ff6f45' : '#606266'}"
              class="jeicon jeicon-khgl-pc"
            />
            <i
              v-else
              class="jeicon jeicon-sitemap"
            />
          </span>
          <span
            :class="data.leaf && data.bean.STATUS != '1' ? 'node-name-disable' : ''"
            class="node-name"
          >{{ node.label }}</span>
          <span
            v-if="type=='group' && !data.leaf"
            class="handle-icons"
          >
            <el-button
              @click.stop.prevent="doEidt(data)"
              type="text"
              icon="jeicon jeicon-automatic-pen"
              size="small"
            />
            <el-button
              @click.stop.prevent="doRemove(node, data)"
              type="text"
              icon="jeicon jeicon-error-small"
              size="small"
            />
          </span>
          <span
            v-if="type=='common' && data.leaf"
            class="dept-text"
          >
            {{ data.bean.DEPTNAME }}
          </span>
        </span>
      </el-tree>
    </div>
  </div>
</template>
<script>
import { debounce } from 'lodash';
import {
  getTreeDatas,
  getTreeDatasAsync,
  getCommonGroup,
  deleteGroup,
  setCommonGroup,
} from '../actions/actions';

export default {
  name: 'Tree',
  props: {
    // tab的name
    type: {
      type: String,
      default: 'common',
    },
    // 配置参数
    options: {
      type: Object,
      default: () => {},
    },
    // 已经选择的所有数据 用于tab切换的 回显
    allSelectList: {
      type: Array,
      default: () => [],
    },
    isClear: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      filterData: [], // 关键字查询数据集
      filterText: '', // 关键字
      props: {
        label: 'text',
        children: 'children',
        isLeaf: 'leaf',
      },
      treeData: [], // tree数据
      expandedKeys: [],
      async: false, // 同步还是异步树 默认同步
      selection: [], // 选中的数据
      expandIds: [],
      checkIds: [],
      showSetNameDialog: false,
      isDouble: false, // 是否是双击
      nodataText: '', // 无数据展示信息
    };
  },
  computed: {
    getTreeData() {
      return this.treeData;
    },
  },
  watch: {
    // 清空
    isClear(nv) {
      if (nv) {
        if (this.options.selectType == 'single') {
          this.$refs.tree.setCurrentKey(null);
        } else {
          this.$refs.tree.setCheckedKeys([]);
        }
      }
    },
  },
  created() {
    // 由于后台 常用和工作组 未处理异步 所以默认是同步 不跟配置走
    if ('common, group'.indexOf(this.type) == -1) {
      this.async = this.options.async;
    }
    // this.nodataText = '';
    /* if (this.type !== 'group') {
      this.loadTree('ROOT', () => {
        // 处理回显逻辑
        this.initValue();
      });
    } */
  },
  mounted() {
    // 增加IE9浏览器类名 处理IE9兼容性样式
    if (Ext.isIE9m) {
      this.$nextTick(() => {
        const doms = document.getElementsByClassName('left-tree');
        for (let i = 0; i < doms.length; i++) {
          const dom = doms[i];
          if (dom.className.indexOf('left-tree-ie9') < 0) {
            dom.classList.add('left-tree-ie9');
          }
        }
      });
    }
  },
  methods: {
    // 回显已选中的数据
    initValue() {
      this.expandIds = [];
      this.checkIds = [];
      if (this.allSelectList.length === 0) return;
      // 默认展开的节点集合
      this.allSelectList.forEach((item) => {
        if (!this.async) {
          if (this.type === 'common' || this.type === 'dept') {
            if (this.expandIds.indexOf(item.id) < 0) {
              this.expandIds.push(item.id);
            }
            if (this.checkIds.indexOf(item.id) < 0) {
              this.checkIds.push(item.id);
            }
          } else {
            this.handleRoleAndGroup(item.id, this.treeData);
          }
        } else {
          this.expandNodeByPath(item);
        }
      });
      this.$nextTick(() => {
        // 单选、多选的默认高亮
        if (this.options.selectType == 'single') {
          // 单选
          this.$refs.tree.setCurrentKey(this.allSelectList[0].id_);
        } else {
          // 多选
          this.$refs.tree.setCheckedKeys(this.checkIds);
        }
      });
      this.selection = this.allSelectList;
    },
    /**
     * @name handleRoleAndGroup
     * @Descripttion:  处理角色和工作组的回显
     * @param {id} 已选人员的id
     * @param {treeData} 当前树的数据
     * @param {bool} 是否选中的状态
     * @return
     */
    handleRoleAndGroup(id, treeData, bool) {
      // 循环树数据
      treeData.forEach((data) => {
        if (data.id === id) {
          if (this.expandIds.indexOf(data.id_) < 0) {
            this.expandIds.push(data.id_);
          }
          if (this.checkIds.indexOf(data.id_) < 0) {
            if (bool !== false) {
              this.checkIds.push(data.id_);
            }
          }
        }
        if (data.children.length > 0) {
          this.handleRoleAndGroup(id, data.children);
        }
      });
    },
    // 全选下面的子级叶子节点 自动展开下级数据
    handleExpandAll(data) {
      // 展开下级节点
      this.loadTree(data.id_, (result) => {
        if (result[0] && result[0].parent && this.expandIds.indexOf(result[0].parent.split('_')[0]) < 0) {
          this.expandIds.push(result[0].parent.split('_')[0]);
        }
      });

      // 全选下面的子级叶子节点
      const params = {
        dic: ['JE_CORE_DEPTUSER'],
        type: 'rootId',
        async: true,
        value: data.id_,
        whereSql: this.options.params_whereSql,
        j_query: this.options.params_jquery,
      };
      switch (this.type) {
        case 'dept':
          params.dic = ['JE_CORE_DEPTUSER'];
          break;
        case 'role':
          params.dic = ['JE_CORE_VROLEUSER_ALL'];
          break;
        default:
          break;
      }
      getTreeDatasAsync(params).then((res) => {
        this.recursionData(res);
        res.forEach((item) => {
          if (item.disable != '1' && !this.isExist(this.selection, item)) {
            this.selection.push(item);
          }
        });
        this.handleSelection();
      });
    },
    // 多选模式下 CheckChange事件
    handleCheckChange(data, checked) {
      if (checked) {
        // 异步处理
        if (this.async) {
          this.expandIds = [];
          this.checkIds = [];
          if (!data.leaf) {
            this.handleExpandAll(data);
          } else if (data.disable != '1' && !this.isExist(this.selection, data)) {
            this.selection.push(data);
            this.handleSelection();
          }
          return;
        }
        // 同步下的处理
        if (data.disable != '1' && !this.isExist(this.selection, data)) {
          this.selection.push(data);
          if (this.type === 'role' || this.type === 'group' || this.type === 'post') {
            this.doCheck(data.id, this.treeData, true);
          }
        } else if (this.expandIds.indexOf(data.id_) < 0) {
          this.expandIds.push(data.id_);
        }
      } else if (data.leaf) {
        const index = this.selection.findIndex(item => item.id == data.id);
        if (index > -1) {
          this.selection.splice(index, 1);
          if (this.type === 'role' || this.type === 'group' || this.type === 'post') {
            this.doCheck(data.id, this.treeData, false);
          }
        }
      }
      this.handleSelection();
    },
    // 选中或取消选中
    handleCheck(data, checkobj) {
      if (!this.async) {
        const { checkedNodes } = checkobj;
        checkedNodes.forEach((item) => {
          if (item.disable != '1' && !this.isExist(this.selection, item)) {
            this.selection.push(item);
          }
        });
        this.handleSelection();
      }
    },
    /**
     * @name doCheck
     * @Descripttion: 处理角色、工作组、岗位 操作选中和取消选中
     * @param {id} 已选人员的id
     * @param {treeData} 当前树的数据
     * @param {bool} 是否选中
     * @return
     */
    doCheck(id, treeData, bool) {
      // 循环树数据
      treeData.forEach((data) => {
        if (data.leaf) {
          if (data.id === id) {
            this.$refs.tree.setChecked(data, bool);
          }
        }
        if (data.children.length > 0) {
          this.doCheck(id, data.children, bool);
        }
      });
    },
    // 节点展开 多选的处理
    handleNodeExpand(data, node) {
      // 父节点 已经选中 则子节点默认选中
      const expandNodes = node.childNodes;
      if (expandNodes.length > 0) {
        expandNodes.forEach((item) => {
          if (item.checked && item.data.disable != '1' && !this.isExist(this.selection, item.data)) {
            this.selection.push(item.data);
          }
        });
        this.handleSelection();
      } else if (expandNodes.length === 0) {
        setTimeout(() => {
          const checkNodes = this.$refs.tree.getCheckedNodes(true);
          checkNodes.forEach((item) => {
            if (item.disable != '1' && !this.isExist(this.selection, item)) {
              this.selection.push(item);
            }
          });
          this.handleSelection();
        }, 1500);
      }
    },
    // 单击节点  增加 防抖  避免双击下 触发单击
    handleNodeClick(data) {
      const deb = debounce(() => {
        if (!this.isDouble) {
          if (this.options.selectType != 'single') return;

          // 若是单选 并且属于可选数据
          if (data.disable != '1' && data.leaf) {
            this.selection = [];
            this.selection.push(data);
            this.handleSelection();
          }
        }
      }, 300);
      deb();
    },
    // 双击节点
    handleDbclick(node, data) {
      if (this.options.selectType != 'single') return;

      // 若是单选 并且属于可选数据
      if (data.disable != '1' && data.leaf) {
        this.selection = [];
        this.selection.push(data);
        this.isDouble = true;
        this.handleSelection(true); // 参数 true 表示 直接关闭窗口
      }
    },
    // 部门和角色 参数处理
    getParams(rootId) {
      const params = {
        dic: ['JE_CORE_DEPTUSER'],
        async: this.options.async,
        rootId: rootId || 'ROOT',
        whereSql: this.options.params_whereSql,
        j_query: this.options.params_jquery,
      };
      switch (this.type) {
        case 'dept':
          params.dic = ['JE_CORE_DEPTUSER'];
          break;
        case 'role':
          params.dic = ['JE_CORE_VROLEUSER_ALL'];
          break;
        case 'post':
          params.dic = ['JE_CORE_VSENTRYUSER'];
          break;
        default:
          break;
      }
      return params;
    },
    // 获取tree数据
    loadTree(id, cb) {
      // 如果是常用和工作组
      if ('common, group'.indexOf(this.type) > -1) {
        getCommonGroup({
          type: this.type,
          status: this.options.status,
        }).then((data) => {
          if (!data.success) {
            return JE.msg('请求失败，请联系开发人员！');
          }
          // 由于后台返回数据 data.obj可能会是[null] 所以过滤掉
          let { obj } = data;
          if (obj && obj[0]) {
            // 后端调用平台方法会返回一个根节点，工作组需要去掉根节点做特殊处理
            if (this.type == 'group') {
              if (obj[0].children && obj[0].children.length > 0) {
                obj = data.obj[0].children;
              }
            }
            this.filterData = [];
            this.recursionData(obj);
            this.treeData = obj;
            if (cb) return cb(obj);
          } else if (this.type == 'common') {
            this.nodataText = this.$t('noData');
            this.$emit('toggle2dept');
          } else {
            this.nodataText = this.$t('noData');
          }
        });
      } else {
        getTreeDatas(this.getParams(id)).then((data) => {
          if (data.length === 0) {
            this.nodataText = this.$t('noData');
          }
          this.filterData = [];
          this.recursionData(data);
          if (id === 'ROOT') {
            this.treeData = data;
          }
          if (cb) return cb(data);
        });
      }
    },
    // 异步模式下  加载下级节点数据
    loadNode(node, resolve) {
      if (node.level === 0) {
        return resolve(this.treeData);
      }
      // 最后一级  return
      if (node.isLeaf) return resolve([]);

      setTimeout(() => {
        this.loadTree(node.data.id_, (data) => {
          resolve(data);

          // 处理异步时节点展开后 已选数据的默认选中
          data.forEach((item) => {
            this.selection.forEach((sel) => {
              if (item.id === sel.id) {
                this.$refs.tree.setChecked(item, true);
              }
            });
          });
        });
      }, 50);
    },
    // 递归筛选数据
    recursionData(data) {
      if (data instanceof Array) {
        data.forEach((item) => {
          if (item) {
            // 记录下系统配置的disabled值  0 可选有效数据  1 不可选无效数据
            item.disable = item.disabled;
            // 默认全部能选
            item.disabled = false;
            // id值转换
            item.id_ = item.id;
            const [keyId0, keyId1] = item.id.split('_');
            // 处理工作组叶子节点的text id
            if ((this.type == 'group' || this.type == 'role' || this.type == 'post') && item.leaf) {
              item.id = keyId1;
              const [text] = item.text.split('_');
              item.text = text;
            } else {
              item.id = keyId0;
            }
            // 如果是同步并且是可选数据 则放入筛选数据集中 方便前端关键字提示
            if (!this.async && item.disable != '1' && !this.isExist(this.filterData, item)) {
              this.filterData.push(item);
            }
            // 有子数据集 递归处理
            if (item.children && item.children.length > 0) {
              this.recursionData(item.children);
            }
          }
        });
      }
    },
    // 前端查询过滤数据
    filterNode(value, data) {
      if (!value) return true;
      return data.text.indexOf(value) !== -1;
    },
    // 关键字查询后的选择
    handleSelect(item) {
      // 展开节点路径
      this.expandNodeByPath(item);
      // 选中节点
      this.selectNode(item);
    },
    /**
     * 选中节点
     */
    selectNode(node) {
      // 单选 并且属于可选数据
      if (this.options.selectType == 'single') {
        this.selection = [];
        this.selection.push(node);
        this.$refs.tree.setCurrentKey(node.id_);
      } else if (!this.isExist(this.selection, node)) {
        // 多选 如果已选数据中没有 并且属于可选数据 就push进去
        this.selection.push(node);
        // 单独处理 角色和工作组的
        if (this.type === 'role' || this.type === 'group' || this.type === 'post') {
          this.doCheck(node.id, this.treeData, true);
        } else {
          this.$refs.tree.setChecked(node, true);
        }
      }
      this.handleSelection();
    },
    /**
     * 展开节点
     */
    expandNodeByPath(node) {
      const paths = (node.nodePath && node.nodePath.split('/')) || [];
      paths.forEach((id, index) => {
        if (JE.isNotEmpty(id) && id !== 'ROOT') {
          if (this.type === 'common' || this.type === 'dept') {
            if (this.expandIds.indexOf(id) < 0) {
              this.expandIds.push(id);
            }
            if (this.checkIds.indexOf(id) < 0) {
              if (index === paths.length - 1) {
                this.checkIds.push(id);
              }
            }
          } else {
            this.handleRoleAndGroup(id, this.treeData, index === paths.length - 1);
          }
        }
      });
    },
    // 根据ID判断数组中是否已存在
    isExist(array, em) {
      return array.filter(item => item.id == em.id).length > 0;
    },
    // 关键字匹配查询
    querySearch(queryString, cb) {
      const { filterData, async } = this;
      // 若果同步
      if (!async) {
        const results = queryString ? filterData.filter(this.createFilter(queryString)) : filterData;
        // 调用 callback 返回建议列表的数据
        return cb && cb(results);
      }
      // 异步处理
      this.doAsyncLoad(data => cb && cb(data));
    },
    // 过滤方法
    createFilter(queryString) {
      return (data) => {
        const keyword = queryString.toLowerCase();
        const text = data.text.toLowerCase();
        const pinyin = JE.toPinYin(text, 'pinyin');
        return text.indexOf(keyword) > -1 || pinyin.indexOf(keyword) > -1;
      };
    },
    // 异步关键字查询
    doAsyncLoad(cb) {
      const params = {
        dic: ['JE_CORE_DEPTUSER'],
        type: 'liketext',
        async: true,
        value: this.filterText,
        whereSql: this.options.params_whereSql,
        j_query: this.options.params_jquery,
      };
      switch (this.type) {
        case 'dept':
          params.dic = ['JE_CORE_DEPTUSER'];
          break;
        case 'role':
          params.dic = ['JE_CORE_VROLEUSER_ALL'];
          break;
        default:
          break;
      }
      getTreeDatasAsync(params).then((data) => {
        this.recursionData(data);
        cb && cb(data);
      });
    },
    // 选中的数据处理
    handleSelection(isSel) {
      this.$emit('doSelected', this.selection, this.treeData.length, isSel);
    },
    // 删除工作组
    doRemove(node, data) {
      JE.confirm(`${this.$t('isDelete')} ${data.text} ?`, (btn) => {
        if (btn == 'ok') {
          deleteGroup({ ids: data.id, type: 'group' }).then((res) => {
            if (res.success) {
              JE.msg(this.$t('deleteSuccess'));
              const { parent } = node;
              const children = parent.data.children || parent.data;
              const index = children.findIndex(d => d.id === data.id);
              children.splice(index, 1);
            } else {
              JE.msg(this.$t('deleteFailure'));
            }
          });
        }
      });
    },
    // 修改工作组里的人员
    doEidt(data) {
      const that = this;
      const ids = [];
      data.children.forEach((item) => {
        ids.push(item.id);
      });
      JE.selectWin({
        title: this.$t('personnel'),
        type: 'tree',
        configInfo: 'JE_CORE_DEPTUSER,,,M',
        whereSql: ' AND STATUS=\'1\' AND VALID=\'1\'',
        j_query: Ext.encode({
          custom: [
            { code: 'STATUS', type: '=', value: '1' },
            { code: 'VALID', type: '=', value: '1' },
          ],
        }),
        value: ids.join(','),
        valueType: 'id',
        callback(res) {
          const newids = [];
          res.forEach((item) => {
            newids.push(item.data.id);
          });
          that.$prompt(that.$t('inputName'), that.$t('prompt'), {
            confirmButtonText: that.$t('confirm'),
            cancelButtonText: that.$t('cancel'),
            closeOnClickModal: false,
            closeOnPressEscape: false,
            inputValidator: this.groupNameValid, // 工作组名称校验
          }).then(({ value }) => {
            setCommonGroup({
              type: 'group',
              ids: newids.join(','),
              groupName: value,
              groupId: data.id,
            }).then((response) => {
              if (!response.success) {
                return JE.msg(that.$t('modifyFailure'));
              }
              JE.msg(that.$t('modifySuccess'));
              that.loadTree('ROOT', () => {
                that.initValue();
              });
            });
          }).catch(() => {
            // console.log('取消');
          });
        },
      });
    },
    // 校验工作组名称输入
    groupNameValid(value) {
      // 不能为空
      if (value == null || !value.trim()) {
        return this.$t('inputEmptyMsg');
      }
      // 最多十个字符
      if (value.trim().length > 10) {
        return this.$t('inputErrorMsg');
      }
    },
  },
};
</script>
<style lang="scss">
.left-tree {
  .bottom-tree {
    overflow: auto;
    height: 300px;
  }
  .person-select-input {
    width: 100%;
    .el-input--small {
      font-size: 14px;
    }
    .el-input__icon {
      font-size: 16px;
    }
  }
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    overflow: hidden;
    font-size: 14px;
    padding-right: 8px;
    .node-icon {
      float: left;
      i {
        font-size: 14px;
      }
    }
    .node-name {
      float: left;
      margin-left: 6px;
    }
    .node-name-disable {
      text-decoration: line-through;
      color: #a9aba9;
    }
    .handle-icons {
      float: right;
      flex: 1;
      text-align: right;
      .el-button--text {
        color: #bbb;
        &:hover {
          color: #2f6bcf;
        }
      }
      .jeicon-automatic-pen {
        font-size: 14px;
      }
    }
    .dept-text {
      float: right;
      flex: 1;
      text-align: right;
      color: #a9aba9;
      font-size: 12px;
    }
  }
}
.left-tree-ie9 {
  .el-tree-node__content {
    overflow: hidden;
  }
  .custom-tree-node {
    float: right;
    width: 80%;
    padding-top: 3px;
    .handle-icons .el-button--small {
      padding: 0;
    }
  }
}
.person-select-autocomplete {
  z-index: 10000000 !important;
  li {
    padding: 7px 20px;
    line-height: normal;
    border-bottom: 1px solid #f6f6f6;
    .name {
      padding-bottom: 3px;
    }
    .addr{
      font-size: 12px;
      color:#ccc;
    }
    &:last-child {
      border-bottom: 0;
    }
  }
}
</style>
